import cv2
import numpy as np
from typing import List, Dict, Any


class Visualizer:
    def __init__(self):
        self.font = cv2.FONT_HERSHEY_SIMPLEX    # 字体
        self.font_scale = 0.6                   # 字体大小
        self.thickness = 2                      # 线条粗细

    def draw_detections(self, frame: np.ndarray, detections: List[Dict[str, Any]]) -> np.ndarray:
        """
        在帧上绘制所有检测到的目标（边界框、标签等）
        :param frame: 原始图像帧（BGR格式）
        :param detections: 检测结果列表，每个元素是一个目标的字典
        :return: 带有可视化标注的新帧
        """
        annotated_frame = frame.copy()          # 复制原始帧，避免修改原始数据

        for det in detections:                  # 遍历每个检测到的目标
            # 获取边界框坐标
            x1, y1, x2, y2 = [int(coord) for coord in det['bbox']]
            color = det['color']                                # 获取目标的颜色
            label = f"{det['class']} {det['confidence']:.2f}"   # 构造标签文本，内容为“类别名 置信度”，如“person 0.98”

            # 绘制边界框
            cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)

            # 绘制标签背景
            label_size, _ = cv2.getTextSize(label, self.font, self.font_scale, self.thickness)  # 获取标签文本的尺寸(宽度和高度)
            label_y = y1 - 10 if y1 - 10 > 10 else y1 + 10                                      # 计算标签的y坐标，避免与边界框重叠

            cv2.rectangle(
                annotated_frame,
                (x1, label_y - label_size[1] - 5),  # 左上角坐标
                (x1 + label_size[0], label_y + 5),  # 右下角坐标
                color,                              # 颜色
                -1                                  # -1表示填充整个矩形
            )

            # 绘制标签文本
            cv2.putText(
                annotated_frame,            # 目标帧
                label,                      # 标签文本
                (x1, label_y),         # 左上角坐标
                self.font,                  # 字体
                self.font_scale,            # 字体大小
                (255, 255, 255),      # 字体颜色（白色）
                self.thickness              # 线条粗细
            )

            # TODO: 识别到危险物品的时候触发警告
            if det['is_danger']:
                # 在这里添加警告触发逻辑
                pass

        return annotated_frame  
